#pragma once
#include "stdafx.h"
#include "mpqarchiveformat.h"
#include "mpqcompression.h"
#include "mpqencryption.h"
#include "mpqfileinfo.h"
#include "mpqquality.h"
#include "stringhandle.h"
#include "temporaryfile.h"
namespace Moonlite {
namespace Data {
namespace Mpq
{
	public ref class TMPQArchive sealed 
	{
	private:
		HANDLE _handle;
		System::String^ _filename;
		System::Object^ _tag;
		bool _disposed;
		void Open(MPQ_ARCHIVE_FORMAT format, unsigned int hashTableSize);
		void Cleanup(bool managed);
		void CheckBadState();
		unsigned int BuildArchiveFlags(MPQ_ARCHIVE_FORMAT format);
		unsigned int BuildFileFlags(MPQ_COMPRESSION compression, MPQ_ENCRYPTION encryption);
		unsigned int BuildWaveFlags(MPQ_QUALITY quality);
	public:
		void Close();
		void Compact();
		bool Exists(System::String^ filename);
		void ExportFile(System::String^ archivedName, System::String^ localFileName);
		void ExportFile(System::String^ archivedName, array<System::Byte>^ data);
		void ExportFile(System::String^ archivedName, array<System::Byte>^ data, int index);
		void Flush();
		System::Collections::Generic::IEnumerable<TMPQFileInfo^>^ GetFiles();
		System::Collections::Generic::IEnumerable<TMPQFileInfo^>^ GetFiles(System::String^ mask);
		System::Collections::Generic::IEnumerable<TMPQFileInfo^>^ GetFiles(System::String^ mask, bool traverseListFileOnly);
		System::Collections::Generic::IEnumerable<TMPQFileInfo^>^ GetFiles(System::String^ mask, System::String^ externalListFile);
		System::Collections::Generic::IEnumerable<TMPQFileInfo^>^ GetFiles(System::String^ mask, System::String^ externalListFile, bool traverseListFileOnly);
		void ImportFile(System::String^ archivedName, System::String^ localFileName);
		void ImportFile(System::String^ archivedName, System::String^ localFileName, MPQ_COMPRESSION compression);
		void ImportFile(System::String^ archivedName, System::String^ localFileName, MPQ_COMPRESSION compression, MPQ_ENCRYPTION encryption);
		void ImportFile(System::String^ archivedName, array<System::Byte>^ data);
		void ImportFile(System::String^ archivedName, array<System::Byte>^ data, MPQ_COMPRESSION compression);
		void ImportFile(System::String^ archivedName, array<System::Byte>^ data, MPQ_COMPRESSION compression, MPQ_ENCRYPTION encryption);
		void ImportListFile(System::String^ filename);
		void ImportListFile(array<System::Byte>^ data);
		void ImportWaveFile(System::String^ archivedName, System::String^ localFileName, MPQ_QUALITY quality);
		void ImportWaveFile(System::String^ archivedName, System::String^ localFileName, MPQ_QUALITY quality, MPQ_COMPRESSION compression);
		void ImportWaveFile(System::String^ archivedName, System::String^ localFileName, MPQ_QUALITY quality, MPQ_COMPRESSION compression, MPQ_ENCRYPTION encryption);
		void ImportWaveFile(System::String^ archivedName, array<System::Byte>^ data, MPQ_QUALITY quality);
		void ImportWaveFile(System::String^ archivedName, array<System::Byte>^ data, MPQ_QUALITY quality, MPQ_COMPRESSION compression);
		void ImportWaveFile(System::String^ archivedName, array<System::Byte>^ data, MPQ_QUALITY quality, MPQ_COMPRESSION compression, MPQ_ENCRYPTION encryption);
		void RemoveFile(System::String^ archivedName);
		void RenameFile(System::String^ archivedName, System::String^ newArchivedName);
		virtual System::String^ ToString() override;
		property int Count { int get(); }
		property LCID Locale { LCID get(); void set(LCID locale); }
		property HANDLE Handle { HANDLE get(); }
		property System::String^ FileName { System::String^ get(); }
		property System::Object^ Tag { System::Object^ get(); void set(System::Object^ tag); }
		property bool IsDisposed { bool get(); }
		TMPQArchive(System::String^ filename);
		TMPQArchive(System::String^ filename, MPQ_ARCHIVE_FORMAT format);
		TMPQArchive(System::String^ filename, MPQ_ARCHIVE_FORMAT format, unsigned int hashTableSize);
		~TMPQArchive();
		!TMPQArchive();
	};
}
}
}